package cn.edu.zzuli.nothinglink.ws;

import cn.edu.zzuli.nothinglink.constant.ResCodeConst;
import cn.edu.zzuli.nothinglink.entity.R;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/live_start/{teaId}")
@Component
@Slf4j
public class LiveStartEndPoint {

    //concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, LiveStartEndPoint> clients = new ConcurrentHashMap<>();

    //当前对应的 session 对象
    private Session session;

    /**
     * 在 websocket 连接建立时调用
     * @param session 注意这个session，并不是 HttpSession
     * @param teaId 当前连接的老师的id。
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "teaId")Integer teaId) {
        this.session = session;
        clients.put(teaId.toString(), this);

    }

    /**
     * 接收到 客户端发送数据时调用
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            R msg = JSON.parseObject(message, R.class);
            if (msg.getCode() == 202) {
                session.getBasicRemote().sendText(JSON.toJSONString(
                        //202 代表当前是心跳检测的回应。
                        R.success().setCode(202)
                                .appendMsg("pong!")
                ));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接时调用
     * @param teaId
     */
    @OnClose
    public void onClose(@PathParam(value = "teaId")Integer teaId){
        System.out.println("teaId close");
        clients.remove(teaId.toString());
    }

    /**
     * 连接异常的时候关闭
     * @param session
     * @param throwable
     */
    @OnError
    public void onError(Session session,
                        @PathParam(value = "teaId")Integer teaId,
                        Throwable throwable) {
        System.out.println(throwable);
        if (clients.containsKey(teaId.toString())) {
            clients.remove(teaId.toString());
        }
    }

    /**
     * 对所有客户端广播这个消息。
     * @param r
     */
    public static void broadCast2AllUsers(R r) {
        r.setCode(ResCodeConst.BROADCAST.code());
        clients.forEach((k, v) -> {
            try {
                if (v.session.isOpen()) {
                    v.session.getBasicRemote()
                            .sendText(JSON.toJSONString(r));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

    }

    public static void send2UserById(Integer teaId, R r) {
        if (clients.containsKey(teaId.toString())) {
            try {
                clients.get(teaId.toString()).session.getBasicRemote()
                        .sendText(JSON.toJSONString(r));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
